home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / smbumount.c.z / smbumount.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  4.5 KB  |  194 lines

  1. /*
  2.  *  smbumount.c
  3.  *
  4.  *  Copyright (C) 1995-1998 by Volker Lendecke
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <signal.h>
  11. #include <pwd.h>
  12. #include <grp.h>
  13. #include <sys/socket.h>
  14. #include <sys/param.h>
  15. #include <netinet/in.h>
  16. #include <netdb.h>
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. /* #include <sys/wait.h> */  /* generates a warning here */
  20. extern pid_t waitpid(pid_t, int *, int);
  21. #include <sys/errno.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24. #include <errno.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27. #include <sys/mount.h>
  28. #include <mntent.h>
  29.  
  30. #include <sys/ioctl.h>
  31. #include <linux/fs.h>
  32. #include <linux/smb.h>
  33. #include <linux/smb_mount.h>
  34. #include <linux/smb_fs.h>
  35.  
  36. #include "includes.h"
  37.  
  38. static char *progname;
  39.  
  40. static void
  41. usage(void)
  42. {
  43.         printf("usage: %s mount-point\n", progname);
  44. }
  45.  
  46. static int
  47. umount_ok(const char *mount_point)
  48. {
  49.         int fid = open(mount_point, O_RDONLY, 0);
  50.         uid_t mount_uid;
  51.  
  52.         if (fid == -1) {
  53.                 fprintf(stderr, "Could not open %s: %s\n",
  54.                         mount_point, strerror(errno));
  55.                 return -1;
  56.         }
  57.         
  58.         if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
  59.                 fprintf(stderr, "%s probably not smb-filesystem\n",
  60.                         mount_point);
  61.                 return -1;
  62.         }
  63.  
  64.         if (   (getuid() != 0)
  65.             && (mount_uid != getuid())) {
  66.                 fprintf(stderr, "You are not allowed to umount %s\n",
  67.                         mount_point);
  68.                 return -1;
  69.         }
  70.  
  71.         close(fid);
  72.         return 0;
  73. }
  74.  
  75. /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
  76.    It is up the *caller* to ensure that the PATH is sensible.  i.e.
  77.    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
  78.    is not a legal pathname for ``/dev/fd0.''  Anything we cannot parse
  79.    we return unmodified.   */
  80. char *
  81. canonicalize (const char *path)
  82. {
  83.     char *canonical = malloc (PATH_MAX + 1);
  84.  
  85.     if (strlen(path) > PATH_MAX)
  86.     {
  87.         fprintf(stderr, "Mount point string too long\n");
  88.         return NULL;
  89.     }
  90.  
  91.     if (path == NULL)
  92.         return NULL;
  93.   
  94.     if (realpath (path, canonical))
  95.         return canonical;
  96.  
  97.     pstrcpy (canonical, path);
  98.     return canonical;
  99. }
  100.  
  101.  
  102. int 
  103. main(int argc, char *argv[])
  104. {
  105.         int fd;
  106.  
  107.         char* mount_point;
  108.  
  109.         struct mntent *mnt;
  110.         FILE* mtab;
  111.         FILE* new_mtab;
  112.  
  113.         progname = argv[0];
  114.  
  115.         if (argc != 2) {
  116.                 usage();
  117.                 exit(1);
  118.         }
  119.  
  120.         if (geteuid() != 0) {
  121.                 fprintf(stderr, "%s must be installed suid root\n", progname);
  122.                 exit(1);
  123.         }
  124.  
  125.         mount_point = canonicalize(argv[1]);
  126.  
  127.     if (mount_point == NULL)
  128.     {
  129.         exit(1);
  130.     }
  131.  
  132.         if (umount_ok(mount_point) != 0) {
  133.                 exit(1);
  134.         }
  135.  
  136.         if (umount(mount_point) != 0) {
  137.                 fprintf(stderr, "Could not umount %s: %s\n",
  138.                         mount_point, strerror(errno));
  139.                 exit(1);
  140.         }
  141.  
  142.         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
  143.         {
  144.                 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
  145.                 return 1;
  146.         }
  147.         close(fd);
  148.     
  149.         if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
  150.                 fprintf(stderr, "Can't open " MOUNTED ": %s\n",
  151.                         strerror(errno));
  152.                 return 1;
  153.         }
  154.  
  155. #define MOUNTED_TMP MOUNTED".tmp"
  156.  
  157.         if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
  158.                 fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
  159.                         strerror(errno));
  160.                 endmntent(mtab);
  161.                 return 1;
  162.         }
  163.  
  164.         while ((mnt = getmntent(mtab)) != NULL) {
  165.                 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
  166.                         addmntent(new_mtab, mnt);
  167.                 }
  168.         }
  169.  
  170.         endmntent(mtab);
  171.  
  172.         if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
  173.                 fprintf(stderr, "Error changing mode of %s: %s\n",
  174.                         MOUNTED_TMP, strerror(errno));
  175.                 exit(1);
  176.         }
  177.  
  178.         endmntent(new_mtab);
  179.  
  180.         if (rename(MOUNTED_TMP, MOUNTED) < 0) {
  181.                 fprintf(stderr, "Cannot rename %s to %s: %s\n",
  182.                         MOUNTED, MOUNTED_TMP, strerror(errno));
  183.                 exit(1);
  184.         }
  185.  
  186.         if (unlink(MOUNTED"~") == -1)
  187.         {
  188.                 fprintf(stderr, "Can't remove "MOUNTED"~");
  189.                 return 1;
  190.         }
  191.  
  192.     return 0;
  193. }    
  194.